﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using AssetManagementSystem.Model;

using System.Net;
using System.Net.Mail;

namespace AssetManagementSystem.Model.Notification {
    public static class NotificationAssistant {

        private static SysPropertyManager propertyManager;

        static NotificationAssistant(){
            propertyManager = new SysPropertyManager();
        }

        /// <summary>
        /// Sends an email notification to the specified student, about the specified loan.
        /// </summary>
        /// <param name="student">The student to be notified</param>
        /// <param name="loan">The loan whos details will be used when generating the notification</param>
        public static void SendNotification(Student student, Loan loan) {
            Dictionary<string, string> fields = GenerateTemplateFields(student, loan);

            var fromAddress = new MailAddress(propertyManager.GetProperty("FromAddress"),
                propertyManager.GetProperty("FromName"));
            var toAddress = new MailAddress(student.EmailAddress, student.FirstName + " " + student.LastName);
            string fromUsername = propertyManager.GetProperty("FromUsername");
            string fromPassword = propertyManager.GetProperty("FromPassword");
            string subject = GenerateEmailSubject(fields);
            string body = GenerateEmailBody(fields);

            bool ssl = false;
            if (propertyManager.GetProperty("SmtpSSL").ToLower() == "true") {
                ssl = true;
            }

            var smtp = new SmtpClient {
                Host = propertyManager.GetProperty("SmtpHost"),
                Port = Convert.ToInt32(propertyManager.GetProperty("SmtpPort")),
                EnableSsl = ssl,
                DeliveryMethod = SmtpDeliveryMethod.Network,
                UseDefaultCredentials = false,
                Credentials = new NetworkCredential(fromUsername, fromPassword)
            };
            using (var message = new MailMessage(fromAddress, toAddress) {
                Subject = subject,
                Body = body
            }) {
                smtp.Send(message);
            }
        }

        /// <summary>
        /// Generates the email subject from the template stored in the system settings.
        /// </summary>
        /// <param name="fields">The fields to be replaced in the template</param>
        /// <returns>The generated subject message</returns>
        private static string GenerateEmailSubject(Dictionary<string, string> fields) {
            string template = propertyManager.GetProperty("EmailSubject");
            return GenerateTemplate(fields, template);
        }

        /// <summary>
        /// Generates the email body from the template stored in the system settings.
        /// </summary>
        /// <param name="fields">The fields to be replaced in the template</param>
        /// <returns>The generated email body</returns>
        private static string GenerateEmailBody(Dictionary<string, string> fields) {
            string template = propertyManager.GetProperty("EmailTemplate");
            return GenerateTemplate(fields, template);
        }

        /// <summary>
        /// Generated a string from a provided template by replacing all fields (keys) with their replacement text (values).
        /// </summary>
        /// <param name="fields">The fields to replace</param>
        /// <param name="template">The template to generate from</param>
        /// <returns>The generated string</returns>
        private static string GenerateTemplate(Dictionary<string, string> fields, string template) {
            foreach (KeyValuePair<string, string> field in fields) {
                template = template.Replace(field.Key, field.Value);
            }
            return template;
        }

        /// <summary>
        /// Given a student and a loan generates a set of tokens and values to be used when generating a notification from
        /// a notification template.
        /// </summary>
        /// <param name="student">The student whos details are to be included in the fields</param>
        /// <param name="loan">The loan whos details are to be included in the fields</param>
        /// <returns>The set of fields to be used when generating notifications</returns>
        private static Dictionary<string, string> GenerateTemplateFields(Student student, Loan loan) {
            Dictionary<string, string> fields = new Dictionary<string, string>();
            fields.Add("<<[Loan.DueDate]>>", loan.DueDate.ToString("dd/MM/yyyy"));
            fields.Add("<<[Loan.StartDate]>>", loan.StartDate.ToString("dd/MM/yyyy"));

            fields.Add("<<[Student.Id]>>", student.StudentId);
            fields.Add("<<[Student.FirstName]>>", student.FirstName);
            fields.Add("<<[Student.LastName]>>", student.LastName);
            fields.Add("<<[Student.Email]>>", student.EmailAddress);

            return fields;
        }

    }
}
